package com.wwj.server.notify;

import com.google.gson.Gson;
import com.wwj.core.wawa.entity.Player;
import com.wwj.core.wawa.service.IPlayerService;
import com.wwj.server.model.Message;
import com.wwj.server.notify.common.MsgConstants;
import com.wwj.server.notify.msg.NotifyServerBindMsgAck;
import com.wwj.server.notify.msg.NotifyUserCatchMsg;
import com.wwj.server.notify.session.SessionManager;
import com.wwj.server.notify.utils.SpringContextUtils;
import com.wwj.server.session.Session;
import com.wwj.server.utils.NettySocketUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 消息接受处理类
 *
 * @author tysci
 */
public class ClientHandler extends SimpleChannelInboundHandler<Message> {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private IPlayerService playerService = (IPlayerService) SpringContextUtils.getContext().getBean("playerServiceImpl");

    //1.连接注册
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        //logger.debug("host:{} 开始连接本机...", NettySocketUtil.getHostName(ctx));
    }

    //2.连接激活
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        //logger.debug("host:{} 连接通道已激活...", NettySocketUtil.getHostName(ctx));
    }

    /**
     * 接收消息
     */
    //3.数据读取
    @Override
    public void channelRead0(ChannelHandlerContext ctx, Message message) throws Exception {
        //消息分类
        //logger.debug("host:{} 开始接收消息...", NettySocketUtil.getHostName(ctx));
        //logger.debug("消息内容：" + new String(message.getData()));
        handlerMessage(message);
    }

    //4.数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
        //logger.debug("host:{} 消息接收完毕...", NettySocketUtil.getHostName(ctx));
    }


    /**
     * 断线移除会话
     */
    //5.连接无效
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.debug("host:{} 远程连接已失效...", NettySocketUtil.getHostName(ctx));
        logger.debug("开始尝试重新进行连接...", NettySocketUtil.getHostName(ctx));
        Main.client.setRegister(false);
        Main.client.rebind();
    }

    //6.连接注销
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        Channel channel = ctx.channel();
        if (!channel.isActive()) {
            logger.info("#######################--服务端-{}断开了长连接！", channel.remoteAddress());
            ctx.close();
        } else {
            ctx.fireExceptionCaught(cause);
            logger.error("#######################", cause);
        }
    }

    /**
     * 消息处理
     *
     * @param message
     */
    private void handlerMessage(Message message) {

        String sessionKey = null;
        Object object;
        switch (message.getType()) {
            //notify注册绑定到control后的回调
            case MsgConstants.NOTIFY_SERVER_BIND_ACK:
                logger.debug("GET Message「ControlServer」:" + new String(message.getData()));
                NotifyServerBindMsgAck notifyServerBindMsgAck = new Gson().fromJson(new String(message.getData()), NotifyServerBindMsgAck.class);
                if (notifyServerBindMsgAck.getResult().toUpperCase().equals("Y")) {
                    Main.client.setRegister(true);
                } else {
                    logger.warn("NotifyServer <--> ControlServer 远程连接失败！");
                }
                break;
            //玩家抓取到娃娃推送通知
            case MsgConstants.NOTIFY_USER_CATCH:
                logger.debug("GET Message「ControlServer」:" + new String(message.getData()));
                NotifyUserCatchMsg userCatchMsg = new Gson().fromJson(new String(message.getData()), NotifyUserCatchMsg.class);
                String userId = userCatchMsg.getUserId();
                if (null != userId && !"".equals(userId)) {
                    sessionKey = SessionManager.PREFIX_SESSION_KEY_USER + userId;
                    Session session = SessionManager.getSession(sessionKey);
                    if (null != session) {
                        object = session.getAttachment();
                        if (object instanceof Player) {
                            Player player = (Player) object;
                            userCatchMsg.setNickname(player.getNickname());
                            userCatchMsg.setHeaderIcon(player.getHeaderIcon());
                            SessionManager.sendMessage(sessionKey, userCatchMsg);
                        }
                    }
                }
                break;
            case MsgConstants.NOTIFY_SERVER_HEARTBEAT_ACK:
                break;
            default:
                logger.error("type not exists");
        }

    }

}
